package com.coldworks.coldjoke.ui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.coldworks.base.manager.BaseBitmapManager;
import com.coldworks.base.manager.BaseNetworkManager;
import com.coldworks.base.manager.BaseStorageManager;
import com.coldworks.base.util.BaseCONST;
import com.coldworks.coldjoke.R;
import com.coldworks.coldjoke.adapter.ReplyAdapter;
import com.coldworks.coldjoke.manager.UserManager;
import com.coldworks.coldjoke.model.ReplyModel;
import com.coldworks.coldjoke.model.TopicModel;
import com.coldworks.coldjoke.task.AsyncImgLoader;
import com.coldworks.coldjoke.task.AsyncImgLoader.UrlImageCallback;
import com.coldworks.coldjoke.task.TopicReplyTask;
import com.coldworks.coldjoke.util.CONST;
import com.coldworks.coldjoke.util.NetworkUtil;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class TopicView extends RelativeLayout {
	protected final Logger log = LoggerFactory.getLogger(this.getClass());

	private Context context;
	private TopicModel topicInfo;

	private LinearLayout topicOperationBar;
	private ResizeListView mainListView;
	private TextView topicTitleView;
	private TextView topicSummaryView;
	private ImageView topicImage;
	private TextView replyNumView;
	private ProgressBar replyLoadingView;
	private EditText commentEditText;
	private Button commentBtn;
	private View header;
	private LinearLayout headerContent;
	private MenuShareTopicView mShareView;

	private List<ReplyModel> list = null;
	private int mScrollState;
	private ReplyAdapter adapter;
	private final int IMAGE_CONDITION_0 = 0;
	private final int IMAGE_CONDITION_1 = 1;

	public TopicView(Context context) {
		super(context);
		setUpViews(context);
	}

	public TopicView(Context context, AttributeSet attrs) {
		super(context, attrs);
		setUpViews(context);
	}

	public TopicView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setUpViews(context);
	}

	private void setUpViews(final Context context) {
		this.context = context;
		header = LayoutInflater.from(context).inflate(
				R.layout.navigation_topic_single, null);
		headerContent = (LinearLayout) header.findViewById(R.id.topic_content);
		topicTitleView = (TextView) header.findViewById(R.id.topic_title);
		topicSummaryView = (TextView) header.findViewById(R.id.topic_summary);
		topicImage = (ImageView) header.findViewById(R.id.topic_image);
		replyNumView = (TextView) header.findViewById(R.id.topic_reply_num);
		replyLoadingView = (ProgressBar) header
				.findViewById(R.id.topic_reply_progress);
		mShareView = new MenuShareTopicView(context);
		mainListView = new ResizeListView(context);
		mainListView.setCacheColorHint(context.getResources().getColor(
				R.color.transparent));
		mainListView.setDividerHeight(5);
		mainListView.setDivider(null);
		mainListView.setSelector(R.color.transparent);
		mainListView.addHeaderView(header);

		LinearLayout empty = new LinearLayout(context);
		empty.setLayoutParams(new ListView.LayoutParams(
				ListView.LayoutParams.MATCH_PARENT, BaseBitmapManager
						.getInstance().dpToPx(context, 60)));
		mainListView.addFooterView(empty);
		topicOperationBar = (LinearLayout) LayoutInflater.from(context)
				.inflate(R.layout.operation_bar_comment, this, false);
		this.addView(mainListView);
		this.addView(topicOperationBar);

		setUpListeners();
	}

	private void setUpListeners() {

		mainListView.setOnScrollListener(new AbsListView.OnScrollListener() {
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// 记录当前状态
				mScrollState = scrollState;
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				// 可视的最后一个列表项的索引
				int lastVisibleItem = firstVisibleItem + visibleItemCount - 1;
				// 当列表正处于滑动状态且滑动到列表底部时，执行
				if (mScrollState != AbsListView.OnScrollListener.SCROLL_STATE_IDLE
						&& lastVisibleItem == totalItemCount - 1) {
				}
			}
		});

		mainListView.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (commentEditText.hasFocus()) {
					commentEditText.clearFocus();
					final InputMethodManager imm = (InputMethodManager) TopicView.this.context
							.getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(
							commentEditText.getWindowToken(), 0);
				}
				return false;
			}
		});

		commentBtn = (Button) topicOperationBar
				.findViewById(R.id.button_comment);
		commentEditText = (EditText) topicOperationBar
				.findViewById(R.id.comment_content);
		commentBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {

				tvUserStateDelegate.TVUScomment();

			}
		});

	}

	// public void startReply() {
	// mainListView.requestFocusFromTouch();
	// mainListView.setSelection(mainListView.getAdapter().getCount() - 1);
	// topicOperationBar.setVisibility(View.INVISIBLE);
	// topicViewFooter.setVisibility(View.VISIBLE);
	//
	// replyInput.requestFocusFromTouch();

	// }

	public class ResizeListView extends ListView {
		public ResizeListView(Context context) {
			super(context);
		}

		@Override
		public boolean onInterceptTouchEvent(MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				// 触摸屏幕时刻,获得触摸的坐标
			}
			return false;
		}
	}

	public void setData(TopicModel topicInfo) {
		clearData();
		this.topicInfo = topicInfo;
		topicTitleView.setText(topicInfo.getTitle());
		topicSummaryView.setText(topicInfo.getSummary());
		replyNumView.setText(topicInfo.getReplyNum() + "条评论");
		new GetGatherOneTask(context, topicInfo.getGatherId()).execute();

		if (!topicInfo.getImgUrl().equals("")) {
			Bitmap cachedImage = AsyncImgLoader.getInstance()
					.loadDrawableByUrl(
							context,
							topicInfo.getImgUrl(),
							topicImage,
							new UrlImageCallback() {
								@Override
								public void imageLoaded(Bitmap imageDrawable,
										ImageView imageView, String imageUrl) {
									imageView.setImageBitmap(imageDrawable);
								}
							}, BaseStorageManager.getInstance().getImgDir(),
							false);
			if (cachedImage != null) {
				topicImage.setImageBitmap(cachedImage);
			} else {
				topicImage.setBackgroundResource(R.drawable.ic_photo);
			}
		}
	}

	private void clearData() {
		topicTitleView.setText("");
		topicSummaryView.setText("");
		topicImage.setBackgroundResource(R.drawable.ic_photo);
		headerContent.removeAllViews();
		list = new ArrayList<ReplyModel>();
		adapter = new ReplyAdapter(context, list);
		mainListView.setAdapter(adapter);
		adapter.notifyDataSetChanged();
	}

	private class GetGatherOneTask extends AsyncTask<Void, Integer, Integer> {

		private Context context;
		private ProgressDialog downPrg;
		private String url;
		private DefaultHttpClient httpclient;
		private String msg = null;

		public GetGatherOneTask(Context context, String topicId) {
			this.context = context;
			this.url = CONST.URL.GATHER + "?action=getOneGather&Gatherid="
					+ topicId;
		}

		@Override
		protected void onPreExecute() {
			this.downPrg = new ProgressDialog(context);
			this.downPrg.setMessage(getResources().getString(
					R.string.topic_fetching));
			this.downPrg.setIndeterminate(true);
			this.downPrg.setCancelable(true);
			this.downPrg.setOnCancelListener(new OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dialog) {
					GetGatherOneTask.this.cancel(true);
				}
			});
			this.downPrg.show();

		}

		@Override
		protected Integer doInBackground(Void... params) {

			HttpGet get = new HttpGet(url);
			httpclient = BaseNetworkManager.getInstance().createHttpClient(
					context);
			try {
				String sessionId = UserManager.getInstance().getSessionId();
				get.setHeader("COOKIE", "webpy_session_id=" + sessionId);
				HttpResponse response = httpclient.execute(get);
				if (response.getStatusLine().getStatusCode() == 200) {
					JSONObject jsonObject = NetworkUtil.getInstance()
							.getJSONObject(response.getEntity().getContent());
					if (jsonObject == null) {
						return BaseCONST.OP.ERR_NET;
					}
					if (jsonObject.has("error")) {
						msg = jsonObject.getString("error");
						return BaseCONST.OP.ERR_NET;
					}
					topicInfo.setTitle(jsonObject.getString("title"));
					topicInfo.setContent(jsonObject.getString("content"));
					String imgUrl = jsonObject.getString("uri");
					if (!imgUrl.equals("") && !imgUrl.startsWith("http")) {
						imgUrl = CONST.URL.HOST + imgUrl;
					}
					topicInfo.setImgUrl(imgUrl);
					topicInfo.setSummary(jsonObject.getString("summary"));
					topicInfo.setType(jsonObject.getString("type"));
					topicInfo.setImages(jsonObject.getString("images"));
					topicInfo
							.setTimeCreated(jsonObject.getString("created_cn"));
					return BaseCONST.OP.SUCC;
				} else {
					log.info(String.valueOf(response.getStatusLine()
							.getStatusCode()));
					return BaseCONST.OP.FAIL;
				}
			} catch (ClientProtocolException e) {
				log.error("", e);
				return BaseCONST.OP.ERR_NET;
			} catch (IOException e) {
				log.error("", e);
				return BaseCONST.OP.ERR_NET;
			} catch (JSONException e) {
				log.error("", e);
				return BaseCONST.OP.ERR_NET;
			}
		}

		@Override
		protected void onPostExecute(Integer result) {
			if (this.downPrg != null) {
				this.downPrg.dismiss();
			}
			switch (result) {
			case BaseCONST.OP.SUCC:
				List<String> paragraphList = new ArrayList<String>();
				List<String> imgsList = new ArrayList<String>();
				topicTitleView.setText(topicInfo.getTitle());
				String content = topicInfo.getContent();
				Matcher data = CONST.PRE_IMG_PATTERN.matcher(content);
				int paragraphStart = 0;
				int image_condition = 0;
				while (data.find()) {
					paragraphList.add(content.substring(paragraphStart,
							data.start()));
					paragraphStart = data.end();
					String temp = data.group();
					if (temp.charAt(6) != '_') {
						image_condition = IMAGE_CONDITION_1;
					}
					imgsList.add(temp.substring(7, temp.length() - 1));
				}

				paragraphList.add(content.substring(paragraphStart));

				if (paragraphList.size() == 0) {
					paragraphList.add(content);
				}

				showTopicView(paragraphList, imgsList, image_condition);
				new FetchRepliesTask(context, adapter, topicInfo.getGatherId(),
						list, "gather").execute();
				log.info("succ");
				break;
			case BaseCONST.OP.ERR_NET:
				if (msg != null) {
					Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
				}
				log.info("error net");
				break;
			case BaseCONST.OP.FAIL:
				log.info("failed");
				Toast.makeText(context, R.string.topic_fetch_err,
						Toast.LENGTH_SHORT).show();
				log.info("failed");
				break;
			}

		}
	}

	private void showTopicView(List<String> paragraphList,
			List<String> imgsList, int image_condition) {
		for (int i = 0; i < paragraphList.size(); i++) {
			TextView textView = new TextView(context);
			textView.setLayoutParams(new LinearLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
			textView.setTextColor(getResources().getColor(R.color.text_color_1));
			textView.setText(paragraphList.get(i));
			textView.setLineSpacing(1, 1.3f);
			textView.setTextSize(17);
			headerContent.addView(textView);
			if (i < imgsList.size()) {
				ImageView imageView = new ImageView(context);
				imageView.setLayoutParams(new LinearLayout.LayoutParams(
						LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
				imageView.setBackgroundResource(R.drawable.ic_photo);
				final String url;

				if (image_condition == IMAGE_CONDITION_0) {
					url = getImgUrl(imgsList.get(i));
				} else {
					url = imgsList.get(i).trim();
				}

				if (url != "") {
					Bitmap cachedImage = AsyncImgLoader.getInstance()
							.loadDrawableByUrl(
									context,
									url,
									imageView,
									new UrlImageCallback() {
										@Override
										public void imageLoaded(
												Bitmap imageDrawable,
												ImageView imageView,
												String imageUrl) {
											imageView
													.setLayoutParams(new LinearLayout.LayoutParams(
															LayoutParams.MATCH_PARENT,
															LayoutParams.WRAP_CONTENT));
											imageView
													.setBackgroundDrawable(null);
											imageView
													.setImageBitmap(imageDrawable);
										}
									},
									BaseStorageManager.getInstance()
											.getTopicDir(), false);
					if (cachedImage != null) {
						imageView.setImageBitmap(cachedImage);
					} else {
						imageView.setBackgroundResource(R.drawable.ic_photo);
					}
				}
				headerContent.addView(imageView);
			}
		}
	}

	private String getImgUrl(String id) {
		try {
			JSONArray imgJsonArray = new JSONArray(topicInfo.getImages());
			for (int i = 0; i < imgJsonArray.length(); i++) {
				if (id.equals(imgJsonArray.getJSONObject(i).getString(
						"UserImageid"))) {
					String url = imgJsonArray.getJSONObject(i).getString("uri");
					if (!url.equals("") && !url.startsWith("http")) {
						url = CONST.URL.HOST + url;
					}
					return url;
				}
			}
		} catch (JSONException e) {
			log.error("", e);
		}
		return id;
	}

	public interface TVUserStateDelegate {
		void TVUScomment();

		void TVUSfavorite();

		void TVUScell();
	}

	private TVUserStateDelegate tvUserStateDelegate;

	public void addTVUserStateDelegate(TVUserStateDelegate tvUserStateDelegate) {
		this.tvUserStateDelegate = tvUserStateDelegate;
	}

	public void share() {
		mShareView.show(this, topicInfo, null);
	}

	public void comment() {
		String url = CONST.URL.GATHER_COMMENT;
		String text = commentEditText.getText().toString();
		if (text.length() == 0) {
			Toast.makeText(context, "随便说点什么吧！", Toast.LENGTH_SHORT).show();
			return;
		}
		if (text.trim().length() == 0) {
			Toast.makeText(context, "元芳，空格键你怎么看！", Toast.LENGTH_SHORT).show();
			return;
		}
		String replyContent = text.trim();
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("action", "postComment"));
		params.add(new BasicNameValuePair("gather_id", String.valueOf(topicInfo
				.getGatherId())));
		params.add(new BasicNameValuePair("joke_id", String.valueOf(topicInfo
				.getGatherId())));
		params.add(new BasicNameValuePair("content", replyContent));
		new TopicReplyTask(context, url, params).start();
		ReplyModel replyInfo = new ReplyModel();
		replyInfo.setReplyContent(replyContent);
		replyInfo.setUserName(UserManager.getInstance().getUserName());
		list.add(replyInfo);
		adapter.notifyDataSetChanged();
		commentEditText.getText().clear();
		commentEditText.clearFocus();
		final InputMethodManager imm = (InputMethodManager) TopicView.this.context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(commentEditText.getWindowToken(), 0);
	}

	public class FetchRepliesTask extends AsyncTask<Void, Void, Integer> {
		private Context context;
		private ReplyAdapter adapter;
		private String url;
		private List<ReplyModel> list;

		public FetchRepliesTask(Context context, ReplyAdapter adapter,
				String id, List<ReplyModel> list, String from) {
			this.context = context;
			this.adapter = adapter;
			if (from.equals("joke")) {
				this.url = CONST.URL.COMENT
						+ "?action=getOneJokeComments&joke_id=" + id
						+ "&page_num=1&data_type=json";
			} else { // from.equals("gather")
				this.url = CONST.URL.GATHER_COMMENT
						+ "?action=getOneGatherComments&data_type=json&gather_id="
						+ id;
			}
			this.list = list;
		}

		@Override
		protected Integer doInBackground(Void... params) {
			DefaultHttpClient httpclient;
			HttpGet get = new HttpGet(url);
			httpclient = BaseNetworkManager.getInstance().createHttpClient(
					context);
			JSONArray jsonArray = null;
			ReplyModel jokeReplyInfo = null;
			try {
				String sessionId = UserManager.getInstance().getSessionId();
				get.setHeader("COOKIE", "webpy_session_id=" + sessionId);
				HttpResponse response = httpclient.execute(get);
				if (isCancelled()) {
					log.info("run", "cancelled");
					return BaseCONST.OP.CANCEL;
				}
				if (response.getStatusLine().getStatusCode() == 200) {
					Header contentEncoding = response
							.getFirstHeader("Content-Encoding");
					JSONObject jsonObject = null;
					if (contentEncoding != null
							&& contentEncoding.getValue().equalsIgnoreCase(
									"gzip")) {
						jsonObject = NetworkUtil.getInstance()
								.getJsonObjectByGzip(
										response.getEntity().getContent());
					} else {
						jsonObject = NetworkUtil.getInstance().getJSONObject(
								response.getEntity().getContent());
					}
					if (jsonObject == null) {
						return BaseCONST.OP.FAIL;
					}
					jsonArray = jsonObject.getJSONArray("comments");
					JSONObject json;
					for (int i = 0; i < jsonArray.length(); i++) {
						jokeReplyInfo = new ReplyModel();
						json = jsonArray.getJSONObject(i);
						JSONObject author = new JSONObject(
								json.getString("author"));
						jokeReplyInfo.setUserName(author.getString("username"));
						jokeReplyInfo.setUserId(json.getString("Userid"));
						jokeReplyInfo
								.setReplyContent(json.getString("content"));
						list.add(jokeReplyInfo);
					}

					return BaseCONST.OP.SUCC;
				} else {
					log.info("status code="
							+ String.valueOf(response.getStatusLine()
									.getStatusCode()));
					return BaseCONST.OP.FAIL;
				}
			} catch (ClientProtocolException e) {
				log.info("", e);
				return BaseCONST.OP.ERR_NET;
			} catch (IOException e) {
				log.info("", e);
				return BaseCONST.OP.FAIL;
			} catch (JSONException e) {
				log.info("", e);
				return BaseCONST.OP.ERR_NET;
			}

		}

		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
			switch (result) {
			case BaseCONST.OP.SUCC:
				adapter.setList(list);
				adapter.notifyDataSetChanged();
				replyLoadingView.setVisibility(View.GONE);
				log.info("success");
				break;
			case BaseCONST.OP.ERR_NET:
				Toast.makeText(context, R.string.err_connecting,
						Toast.LENGTH_LONG).show();
				log.info("error net");
				break;
			case BaseCONST.OP.FAIL:
				log.info("failed");
				break;
			case BaseCONST.OP.CANCEL:
				break;
			}
		}

	}
}
